package br.com.dyad.commons.data;

import java.util.List;

import br.com.dyad.commons.data.events.DataListEvent;
import br.com.dyad.commons.data.events.DataListListener;
import br.com.dyad.commons.data.events.EntityPropertyEvent;

public class DataListView extends DataList implements DataListListener {

	private String viewFieldNames;
	private Object[] viewFieldValues;
	private DataList parent;
	
	public DataListView( DataList parent, String viewFieldNames, Object... viewFieldValues ){
		this.parent = parent;
		parent.addDataListListener(this);
		setViewFieldNames(viewFieldNames);
		setViewFieldValues(viewFieldValues);
		setTransactionalSession( parent.getTransactionalSession());		
	}
	
	public String getViewFieldNames() {
		return viewFieldNames;
	}

	public void setViewFieldNames(String viewFieldNames) {
		this.viewFieldNames = viewFieldNames;
	}

	public Object[] getViewFieldValues() {
		return viewFieldValues;
	}

	public void setViewFieldValues(Object[] viewFieldValues) {
		this.viewFieldValues = viewFieldValues;
	}
	
	public DataList getParent() {
		return parent;
	}

	public void setParent(DataList parent) {
		this.parent = parent;
	}

	@Override
	public void onAfterAddEntityOnList(DataListEvent event, AppEntity appEntity) {
		try {
			Boolean addOnView = verifyAddOnView(appEntity);			
			if ( addOnView ){
				Boolean originalLogChanges = this.getLogChanges();
				this.setLogChanges(false);
				this.add(appEntity);
				this.setLogChanges(originalLogChanges);
			}
			/*HashMap<Long, AppEntity> range = source.getRange(viewFieldNames, viewFieldValues);
			if ( range != null && range.containsKey( appEntity.getId() ) && ! this.findId( appEntity ) ){
				Boolean originalLogChanges = this.getLogChanges();
				this.setLogChanges(false);
				this.add(appEntity);
				this.setLogChanges(originalLogChanges);
			}*/
		} catch (Exception e) {
			throw new RuntimeException(e);
		}		
	}
	
	/**
	 * Verifica se o object atende ao filtro da view.
	 * @param appEntity
	 * @return
	 */
	protected Boolean verifyAddOnView(AppEntity appEntity){
		String[] split = viewFieldNames.split(";");
		Boolean addOnView = true;
		for (int i = 0; i < split.length; i++) {
			Object fieldValue = getFieldValue(appEntity, split[i]);
			Object object = viewFieldValues != null ? viewFieldValues[i] : null;
			if ( (fieldValue == null && object == null) || (fieldValue != null && fieldValue.equals(object)) ){
				addOnView = false;
			}
		}
		return addOnView;
	}

	@Override
	public void onAfterChangeEntityProperty(EntityPropertyEvent event,
			String propertyName, Object value) {
		try {
			AppEntity appEntity = (AppEntity)event.getSource();
			Boolean addOnView = verifyAddOnView(appEntity);			
			if ( addOnView ){
				Boolean originalLogChanges = this.getLogChanges();
				this.setLogChanges(false);
				this.add(appEntity);
				this.setLogChanges(originalLogChanges);
			}
			/*AppEntity appEntity = (AppEntity)event.getSource();
			HashMap<Long, AppEntity> range = this.parent.getRange(viewFieldNames, viewFieldValues);
			if ( range != null && range.containsKey( appEntity.getId() ) && ! this.findId( appEntity ) ){
				Boolean originalLogChanges = this.getLogChanges();
				this.setLogChanges(false);
				this.add(appEntity);
				this.setLogChanges(originalLogChanges);
			}*/
		} catch (Exception e) {
			throw new RuntimeException(e);
		}		
	}

	@Override
	public void onAfterDeleteEntity(DataListEvent event, AppEntity entity) {
		try {
			Boolean originalLogChanges = this.getLogChanges();
			this.setLogChanges(false);
			if ( this.findId(entity) ){
				this.delete(entity);
			}
			this.setLogChanges(originalLogChanges);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public void onAfterEmpty(DataListEvent event) {
		try {
			Boolean originalLogChanges = this.getLogChanges();
			this.setLogChanges(false);
			this.empty();
			this.setLogChanges(originalLogChanges);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public void onAfterNewEntity(DataListEvent event, AppEntity baseEntity) {
	}

	@Override
	public void onAfterSetList(DataListEvent event, List list) {
		try {
			this.rebuildView(this, (DataList)event.getSource(), this.viewFieldNames, this.viewFieldValues);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public void onBeforeAddEntityOnList(DataListEvent event, AppEntity appEntity) {
	}

	@Override
	public void onBeforeDeleteEntity(DataListEvent event, AppEntity entity) {
	}

	@Override
	public void onBeforeEmpty(DataListEvent event) {
	}

	@Override
	public void onBeforeNewEntity(DataListEvent event, AppEntity baseEntity) {
	}

	@Override
	public void onBeforeSetList(DataListEvent event, List list) {
	}

}
